﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using Microsoft.Dynamics.BusinessConnectorNet;
using System.Net;
using System.Collections;
using System.Text;
using System.DirectoryServices.AccountManagement;

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
// [System.Web.Script.Services.ScriptService]

public class Service : System.Web.Services.WebService
{
    private Axapta m_obj;

    public Service () {

        //Uncomment the following line if using designed components 
        //InitializeComponent(); 
    }

    [WebMethod]
    public UserInfo GetUserInfo(string _userId)
    {
        
        // Create the .NET Business Connector objects.
        Axapta ax;
        AxaptaRecord axRecord;
        string tableName = "UserInfo";
        UserInfo userInfo = null;

        // The LogisticsAddressState field names for calls to
        // the AxRecord.get_field method.
        string strUserName = "NAME";
        string strUserld = "ID";
        string strUserAlias = "Alias";
        string strUserCompany = "Company";
        string strUserDomain = "networkDomain";

        // The output variables for calls to the 
        // AxRecord.get_Field method.
        object userName, userId, userAlias, userCompany, userDomain; 

        try
        {
            // Login to Microsoft Dynamics AX.
            ax = new Axapta();
            ax.Logon(null, null, null, null);

            // Create a query using the AxaptaRecord class
            // for the StateAddress table.
            using (axRecord = ax.CreateAxaptaRecord(tableName))
            {

                // Execute the query on the table.
                axRecord.ExecuteStmt("select * from %1 where %1.id == '" + _userId + "'");

                // Create output with a title and column headings
                // for the returned records.

                // Loop through the set of retrieved records.
                while (axRecord.Found)
                {
                    // Retrieve the record data for the specified fields.
                    userName = axRecord.get_Field(strUserName);
                    userId = axRecord.get_Field(strUserld);
                    userAlias = axRecord.get_Field(strUserld);
                    userDomain = axRecord.get_Field(strUserDomain);
                    userCompany = axRecord.get_Field(strUserCompany);


                    userInfo = new UserInfo(userId.ToString(), userName.ToString(), userAlias.ToString(),userDomain.ToString(), userCompany.ToString());

                    // Advance to the next row.
                    axRecord.Next();
                }

                // Keep the console window open.
            }
        }

        catch (Exception e)
        {
            // Take other error action as needed.
        }

        return userInfo;
    }

    [WebMethod]
    public string CreateUser(string _userId, string _userName, string _alias, string _domain, string _company)
    {
        Axapta ax;
        AxaptaRecord axRecord;
        string tableName = "UserInfo";

        try
        {
            // Login to Microsoft Dynamics AX.
            ax = new Axapta();

            ax.Logon(null, null, null, null);

            // Create a new AddressState table record.
            using (axRecord = ax.CreateAxaptaRecord(tableName))
            {
                // Provide values for each of the AddressState record fields.
                axRecord.set_Field("id", _userId);
                axRecord.set_Field("name", _userName);
                axRecord.set_Field("networkAlias", _alias);
                axRecord.set_Field("networkDomain", _domain);
                axRecord.set_Field("company", _company);
                axRecord.set_Field("enable", 1);

                // Commit the record to the database.
                axRecord.Insert();
            }

        }
        catch (Exception exc)
        {
            return exc.Message + " createdWithUser=" + Environment.UserName;
        }

        return "Success";
    }

    [WebMethod]
    public bool DeleteUser(string _userId)
    {
        Axapta ax;
        AxaptaRecord axRecord;
        string tableName = "UserInfo";
        try
        {
            // Login to Microsoft Dynamics AX.
            ax = new Axapta();
            ax.Logon(null, null, null, null);
            // Update the ‘High Priority Customer’    table record.
            using (axRecord = ax.CreateAxaptaRecord(tableName))
            {

                // Execute a query to retrieve an editable record where the StatGroupName is “High Priority Customer”.
                axRecord.ExecuteStmt("select forupdate * from %1 where %1.id =='"+ _userId +"'");
                // If the record is found then update the record.
                if (axRecord.Found)
                {
                    // Start a transaction that can be committed.
                    ax.TTSBegin();
                    axRecord.set_Field("enable", 0);
                    axRecord.Update();
                    // Commit the transaction.
                    ax.TTSCommit();
                    return true;
                }
                else
                {
                    throw new Exception("User not found");
                }
            }
        }
        catch (Exception exc)
        {
            // Take other error action as needed.
            throw new Exception(exc.Message);
        }

    }

    [WebMethod]
    public string CreateUserTool(string _userId, string _alias, string _name, string _externalUser, string _domain, string _email, string _userGroups, string _company)
    {
        Axapta ax;
        object o;
        bool b;
        AxaptaObject m_class = null;

        try
        {
            // Login to Microsoft Dynamics Ax.
            ax = new Axapta();
            ax.Logon(null, null, null, null);

        }
        catch (Exception exc)
        {
            throw new Exception("Logon exception:" + exc.Message);
        }

        // Logon was successful.
        string ret = string.Empty;
        if (DoesUserExist(_name, _domain))
        {
            try
            {
                // Call a static class method.
                // In this example, call SysLabel::labelId2String2 
                // to determine the label string for a particular label ID.
                m_class = ax.CreateAxaptaObject("elsUserManagementHelper");
                ret = (string)m_class.Call("createUser", _userId, _alias, _name, _externalUser, _domain, _email, _userGroups, _company);
            }
            catch (Exception exc)
            {
                b = ax.Logoff();
                throw new Exception("Exception:" + exc.Message);
            }



            // Log off from Microsoft Dynamics AX.
            b = ax.Logoff();
        }
        else
        {
            ret = "User does not exist.";
        }

        return ret;
    }

    [WebMethod]
    public List<UserGroup> GetUserGoups()
    {
        UserGroup userGroup = null;
        List<UserGroup> userGroupList = new List<UserGroup>();

        // Create the .NET Business Connector objects.
        Axapta ax;
        AxaptaRecord axRecord;
        string tableName = "UserGroupInfo";

        // The LogisticsAddressState field names for calls to
        // the AxRecord.get_field method.
        string strUserGroupld = "id";

        // The output variables for calls to the 
        // AxRecord.get_Field method.
        object userGroupId;

        try
        {
            // Login to Microsoft Dynamics AX.
            ax = new Axapta();
            ax.Logon(null, null, null, null);

            // Create a query using the AxaptaRecord class
            // for the StateAddress table.
            using (axRecord = ax.CreateAxaptaRecord(tableName))
            {

                // Execute the query on the table.
                axRecord.ExecuteStmt("select * from %1");

                // Create output with a title and column headings
                // for the returned records.

                // Loop through the set of retrieved records.
                while (axRecord.Found)
                {
                    // Retrieve the record data for the specified fields.
                    userGroupId = axRecord.get_Field(strUserGroupld);

                    userGroup = new UserGroup(userGroupId.ToString());
                    userGroupList.Add(userGroup);

                    // Advance to the next row.
                    axRecord.Next();
                }

                // Keep the console window open.
            }
        }

        catch (Exception exc)
        {
            // Take other error action as needed.
        }

        

        return userGroupList;        
    }

    [WebMethod]
    public List<Company> GetCompanies()
    {
        UserGroup userGroup = null;
        List<Company> companyList = new List<Company>();

        // Create the .NET Business Connector objects.
        Axapta ax;
        AxaptaRecord axRecord;
        string tableName = "DataArea";

        // The LogisticsAddressState field names for calls to
        // the AxRecord.get_field method.
        string strCompanyld = "id";

        // The output variables for calls to the 
        // AxRecord.get_Field method.
        object companyId;

        try
        {
            // Login to Microsoft Dynamics AX.
            ax = new Axapta();
            ax.Logon(null, null, null, null);

            // Create a query using the AxaptaRecord class
            // for the StateAddress table.
            using (axRecord = ax.CreateAxaptaRecord(tableName))
            {

                // Execute the query on the table.
                axRecord.ExecuteStmt("select * from %1");

                // Create output with a title and column headings
                // for the returned records.

                // Loop through the set of retrieved records.
                while (axRecord.Found)
                {
                    // Retrieve the record data for the specified fields.
                    companyId = axRecord.get_Field(strCompanyld);

                    companyList.Add(new Company(companyId.ToString()));

                    // Advance to the next row.
                    axRecord.Next();
                }

                // Keep the console window open.
            }
        }

        catch (Exception exc)
        {
            // Take other error action as needed.
            throw new Exception("Error retrieving companies: " + exc.Message);
        }



        return companyList;
    }


    public string CallMethod(string aClass, string method, object[] args)
    {
        AxaptaObject m_class = null;

        try
        {
            m_class = m_obj.CreateAxaptaObject(aClass);

            object temp = m_class.Call(method, args);
            return temp.ToString();
        }
        catch (Exception e)
        {
            //Record already exists or bad arguments
            //Write to log file and send alert
            throw e;
        }

        return string.Empty;
    }
        
    private bool DoesUserExist(string _userName, string _domain)
    {
        bool exists = false;
        try
        {
            using (var domainContext = new PrincipalContext(ContextType.Domain, _domain))
            {
                using (var foundUser = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, _userName))
                {
                    exists = true;
                }
            }
        }
        catch (Exception exc)
        {
            //Exception could occur if machine is not on a domain
            //throw new Exception("User doesn't exist: " + exc.Message);
            return exists;
        }
        using (var domainContext = new PrincipalContext(ContextType.Machine))
        {
            using (var foundUser = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, _userName))
            {
                exists = true;
            }
        }
        return exists;
    }

    
}